# written by darren.ha(nberserk@gmail.com)
# Warning: supports VS2005 only. not tested any other version 

# usage example:
# powershell .\vcproj2cmake.ps1 c:\xxx.vcproj -slnConf "Debug`|win32"

param(
[string] $file=$(throw 'vcproj file is required'),
[string] $conf='Debug|Win32'
)

$CMake_Template = @'
# -*- cmake -*-

PROJECT(<module>)

## section: include directory
# add your target-specific include directory here. 
    
INCLUDE_DIRECTORIES(
  <include>
  )

## section: source files
# add your source files here
SET (<module>_SOURCE_FILES
    <src>
    )

## section: header files
# add your header files here
SET(<module>_HEADER_FILES
    <header>
    )

SET_SOURCE_FILES_PROPERTIES(<module>_HEADER_FILES
                            PROPERTIES HEADER_FILE_ONLY TRUE)
LIST(APPEND <module>_SOURCE_FILES ${<module>_HEADER_FILES})

## section: add definitions
ADD_DEFINITIONS(${OSP_DEFINITIONS} <def>)

## section: add target
ADD_LIBRARY (<module> SHARED ${<module>_SOURCE_FILES} )

## section: add dependency
ADD_DEPENDENCIES(<module> <lib>)

## section: set link libraries
# DO NOT add suffix(.lib .so) to lib name.
TARGET_LINK_LIBRARIES( <module>
    <lib>    )
'@


function ConvToCMake($vcprojFile, $prjConf){
    if (!(Test-Path $vcprojFile)){    throw "check the following path; $vcprojFile" }
    $files = @()
    [xml]$proj  = gc $vcprojFile
    $proj.selectNodes("/VisualStudioProject/Files//File") | 
        % {
            $_.RelativePath
            if ($_.FileConfiguration -and ($_.FileConfiguration.GetType().name -eq 'Object[]')){
                #$_.RelativePath             
                $exclude = $false
                foreach ($f in $_.FileConfiguration){
                    #$f
                    if ($f.Name -eq $prjConf -and $f.ExcludedFromBuild -eq 'true'){
                        $exclude = $true
                        Write-Host skipping $_.RelativePath
                        break
                    }
                }                
                if (!$exclude){
                    #Write-Host adding $_.RelativePath 
                    $file = $_.RelativePath -replace '\\','/'; $files+=$file            
                }
                
                #$_.SelectSingleNode("FileConfiguration[@Name=""$slnConf""][@excludedFromBuild=yes]")
                #$_.FileConfiguration
                #$destNode
                #Read-Host
            }elseif ($_.FileConfiguration ){
                if ($_.FileConfiguration.Name -eq $prjConf -and $_.FileConfiguration.ExcludedFromBuild -eq 'true'){                
                    Write-Host skipping $_.RelativePath 
                }else{                
                    $file = $_.RelativePath -replace '\\','/'; $files+=$file
                }
            }else{
                #Write-Host adding $_.RelativePath 
                $file = $_.RelativePath -replace '\\','/'; $files+=$file
            }            
        }
    
    $src=@()
    $header=@()
    foreach ($f in $files)
    {
        if ($f -match '\.h'){
            $header += $f
        }else{
            $src += $f
        }
    }
    $header = $header | sort
    $src = $src | sort
    
    # header & src files
    $text = $CMake_Template -replace '<src>',[string]::Join("`n`t", $src)
    $text = $text -replace '<header>',[string]::Join("`n`t", $header)
    $text = $text -replace '<module>',$proj.VisualStudioProject.name
    # link lib
    $target = $proj.SelectSingleNode("/VisualStudioProject/Configurations/Configuration[@Name=""$prjConf""]/Tool[10]")
    $raw = $target.AdditionalDependencies
    $raw = $raw -replace '\.lib',''
    $text = $text -replace '<lib>',$raw
    # definition    
    $target = $proj.SelectSingleNode("/VisualStudioProject/Configurations/Configuration[@Name=""$prjConf""]/Tool[6]")
    $target.PreprocessorDefinitions
    $text = $text -replace '<def>',$target.PreprocessorDefinitions
    #include     
    $raw = $target.AdditionalIncludeDirectories
    $raw = $raw -replace '\\','/'
    $raw = $raw -replace ';',"`n`t"
    $text = $text -replace '<include>',$raw
    
    #save
    $path = Split-Path $vcprojFile
    $text | Out-File (Join-Path $path CMakeLists.txt) -Encoding ASCII
}

ConvToCMake $file $conf